package com.xcm.service.impl;

import com.google.common.collect.Maps;
import com.xcm.config.CustomProperties;
import com.xcm.exception.ServiceException;
import com.xcm.service.FileService;
import net.dongliu.apk.parser.ApkFile;
import net.dongliu.apk.parser.bean.ApkMeta;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.rmi.ServerException;
import java.text.DecimalFormat;
import java.util.Map;

/**
 * 文件Service实现类
 */
@Service(value = "fileService")
public class FileServiceImpl implements FileService {
	@Autowired
	private CustomProperties customProperties;

	/**
	 * 保存文件(如果要返回文件的下载信息，需要传入下载文件路径和封装分析消息的Map)
	 * @param file  MultipartFile
	 * @throws IOException
	 */
	@Override
	public Map<Object, Object> saveApkFile(MultipartFile file) throws IOException {
		//apk文件保存路径
		String fileSavePath = customProperties.getApkFileSavePath();
		if (StringUtils.isBlank(fileSavePath)) {
			throw new ServerException("apk文件保存路径不能为空");
		}
		//文件下载路径
		String fileDownloadPath = customProperties.getFileDownloadPath();
		if (StringUtils.isBlank(fileDownloadPath)) {
			throw new ServerException("文件下载路径不能为空");
		}
		//保存文件
		saveFile(file, fileSavePath);
		//原始文件名
		String originalFilename = file.getOriginalFilename();
		//系统分割符
		String separator = File.separator;
		//文件完整路径
		String fileFullPath = "";
		//如果路径没有配置系统分隔符，
		if (fileSavePath.endsWith(separator)) {
			fileFullPath = fileSavePath + originalFilename;
		} else {
			fileFullPath = fileSavePath + separator + originalFilename;
		}
		Map<Object, Object> msgMap = Maps.newHashMap();
		//获取apk信息
		try (ApkFile apkFile = new ApkFile(new File(fileFullPath))) {
			ApkMeta apkMeta = apkFile.getApkMeta();
			msgMap.put("name", apkMeta.getName());
			msgMap.put("versionCode", apkMeta.getVersionCode());
			msgMap.put("versionName", apkMeta.getVersionName());
			double size = file.getSize() / 1024 / 1024;
			DecimalFormat decimalFormat  =   new  DecimalFormat("##0.0");
			msgMap.put("size", decimalFormat.format(size));
		}
		//如果文件下载路径不为空，需要返回文件信息
		if (StringUtils.isNotBlank(fileDownloadPath) && msgMap != null) {
			//文件名(不包含后缀名)
			String fileName = originalFilename.substring(0, originalFilename.lastIndexOf("."));
			//文件绝对上传路径
			String fullFileUploadPath = fileDownloadPath + File.separator + originalFilename;
			msgMap.put("file", buildPathName(fullFileUploadPath));
			msgMap.put("filename", fileName.toString());
		}
		return msgMap;
	}
	private String buildPathName(String contextFileName) {
		return contextFileName.toString().replace("\\", "/");
	}

	/**
	 * 保存文件公共方法
	 * @param file  MultipartFile
	 * @param fileSavePath  文件保存路径
	 */
	private void saveFile(MultipartFile file, String fileSavePath) throws IOException {
		if (file == null) {
			throw new ServerException("传入文件不能为空");
		}
		//验证文件保存路径
		if (StringUtils.isBlank(fileSavePath)) {
			throw new ServerException("文件保存路径为空");
		}
		String separator = File.separator;
		//如果路径有配置系统分隔符
		if (!fileSavePath.endsWith(separator)) {
			fileSavePath = fileSavePath + separator;
		}
		// 判断文件夹是否存在
		File diskFile = new File(fileSavePath);
		if (!diskFile.exists()) {
			diskFile.mkdirs();
		}

		String originalFilename = file.getOriginalFilename();
		String fullSavePath = fileSavePath + originalFilename;
		//目标文件
		File destFile = new File(fullSavePath);
		if (destFile.exists()) {
			destFile.delete();
		}
		//保存文件
		try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(destFile))) {
			byte[] bytes = file.getBytes();
			stream.write(bytes);
		}
	}

	/**
	 * 下载文件
	 * @param fileName  文件名
	 * @param fileSavePath  文件保存路径
	 * @param response  HttpServletResponse
	 */
	@Override
	public void downloadLocalFile(String fileName, String fileSavePath, HttpServletResponse response) throws ServiceException, IOException {
		if (StringUtils.isBlank(fileName)) {
			throw new ServiceException("文件名为空");
		}
		if (StringUtils.isBlank(fileSavePath)) {
			throw new ServiceException("文件保存路径为空");
		}
		//buffer输入流
		BufferedInputStream bis = null;
		//输出流
		OutputStream os = null;
		//buffer输出流
		BufferedOutputStream bos = null;
		try {
			//设置reponse文件下载信息
			response.setContentType("application/octet-stream;charset=UTF-8");
			response.setCharacterEncoding("UTF-8");
			response.setHeader("Content-disposition", "attachment;filename="+ fileName);
			if (!fileSavePath.endsWith(File.separator)) {
				fileSavePath = fileSavePath + File.separator;
			}
			//获取目标文件的绝对路径
			String fullFileName = fileSavePath + fileName;
			bis = new BufferedInputStream(new FileInputStream(new File(fullFileName)));
			os = response.getOutputStream();
			bos = new BufferedOutputStream(os);

			byte[] buffer = new byte[1024];
			int len = bis.read(buffer);
			while(len != -1){
				bos.write(buffer, 0, len);
				len = bis.read(buffer);
			}
			bos.flush();
		} finally {
			if(bis != null){
				try{
					bis.close();
				}catch(IOException e){}
			}
			if(bos != null){
				try{
					bos.close();
				}catch(IOException e){}
			}
		}
	}

}
